using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreShop.Library;
using CoreShop.Model;
using CoreShop.Repository;
using SqlSugar;
using SqlSugar.Extensions;

namespace CoreShop.Services
{
    /// <summary>
    /// 桌位表 接口实现
    /// </summary>
    public class corecmsfooddeskServices : Repository<corecmsfooddesk>, IcorecmsfooddeskServices
    {
        public bool InsertAsync(corecmsfooddesk entity)
        {
            return base.Change<corecmsfooddesk>().Insert(entity);
        }
        public bool InsertOrUpdate(List<corecmsfooddesk> entity)
        {
            return base.InsertOrUpdate(entity);
        }
        /// <summary>
        /// 重写异步更新方法
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool UpdateAsync(corecmsfooddesk entity)
        {
            return base.Change<corecmsfooddesk>().Update(a => new corecmsfooddesk()
            {
                number = entity.number,
                name = entity.name,
                updateTime = DateTime.Now,
                modifyBy = entity.modifyBy
            }, a => a.id == entity.id);
        }

        /// <summary>
        /// 重写异步更新方法
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool UpdateAsync(List<corecmsfooddesk> entity)
        {
            bool returnKey = true;
            foreach (var item in entity)
            {
                returnKey = base.Change<corecmsfooddesk>().Update(a => new corecmsfooddesk()
                {
                    number = item.number,
                    name = item.name,
                    updateTime = DateTime.Now,
                    modifyBy = item.modifyBy
                }, a => a.id == item.id);
            }
            return returnKey;
        }

        /// <summary>
        /// 重写删除指定ID的数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteByIdAsync(long id)
        {
            return base.Change<corecmsfooddesk>().Update(a => new corecmsfooddesk()
            {
                isDelete = true,
                updateTime = DateTime.Now
            }, a => a.id == id);
        }

        /// <summary>
        /// 重写删除指定ID集合的数据(批量删除)
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public bool DeleteByIdsAsync(int[] ids)
        {
            bool returnKey = true;
            foreach (int id in ids)
            {
                returnKey = base.Change<corecmsfooddesk>().Update(a => new corecmsfooddesk()
                {
                    isDelete = true,
                    updateTime = DateTime.Now
                }, a => a.id == id);
            }
            return returnKey;
        }


        #region 获取缓存的所有数据==========================================================

        /// <summary>
        /// 获取缓存的所有数据
        /// </summary>
        /// <returns></returns>
        public List<corecmsfooddesk> GetCaChe()
        {
            return base.GetList();
        }

        #endregion


        #region 根据条件查询分页数据
        /// <summary>
        /// 根据条件查询分页数据
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public List<corecmsfooddesk> QueryPageAsync(ref int count, int? pageIndex, int? pageSize, string sName)
        {
            List<corecmsfooddesk> custos = new List<corecmsfooddesk>();
            var where = Expressionable.Create<corecmsfooddesk>();
            where = where.And(a => a.isDelete == false);
            if (!string.IsNullOrEmpty(sName))
            {
                where = where.And(a => a.name.Contains(sName))
                    .Or(a => a.number.Contains(sName)).Or(a => a.name.Contains(sName));
            }
            if (pageIndex >= 1 && pageSize > 0)
            {
                custos = base.AsQueryable().WhereIF(true, where.ToExpression())
                    .ToPageList((int)pageIndex, (int)pageSize, ref count)
                    .OrderBy(a => a.number).ToList();
            }
            else
            {
                custos = base.AsQueryable().WhereIF(true, where.ToExpression()).OrderBy(a => a.number).ToList();
            }
            return custos;
        }
        #endregion

        #region
        /// <summary>
        /// 根据条件查询数据
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public List<corecmsfooddesk> QueryAsync(long typeId)
        {
            List<corecmsfooddesk> list = new List<corecmsfooddesk>();
            var where = Expressionable.Create<corecmsfooddesk>();
            where = where.And(a => a.isDelete == false && a.status == 1 && a.id > 0);
            if (typeId > 0)
            {
                where = where.And(a => a.typeId == typeId);
            }
            list = base.AsQueryable().WhereIF(true, where.ToExpression()).OrderBy(a => a.sort).ToList();

            return list;
        }

        /// <summary>
        /// 根据条件查询数据
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public List<corecmsfooddesk> QueryDeskAndStatus(long typeId, int status, string sName = "", long deskId = 0)
        {
            var where1 = Expressionable.Create<corecmsfoodorderingmaster>();
            if (deskId > 0)
                where1 = where1.And(p => p.deskId == deskId);
            else
                where1 = where1.And(p => p.deskId > 0);
            if ((status > (int)GlobalEnumVars.TableStatus.Empty) && (status != (int)GlobalEnumVars.TableStatus.InUse))
            {
                where1 = where1.And(p => p.status == status);
            }
            var orderingMasters = new corecmsfoodorderingmasterServices().AsQueryable().Where(where1.ToExpression()).ToList();
            List<corecmsfooddesk> list = new List<corecmsfooddesk>();
            var where = Expressionable.Create<corecmsfooddesk>();
            where = where.And(a => a.isDelete == false && a.status == 1 && a.id > 0);
            sName = sName.Trim();
            if (deskId > 0)
                where = where.And(p => p.id == deskId);
            if (!string.IsNullOrEmpty(sName)) where = where.And(p => p.name.Contains(sName) || p.number.Contains(sName));
            if (typeId > 0)
                where = where.And(a => a.typeId == typeId);

            if (status > (int)GlobalEnumVars.TableStatus.All)
            {
                var orderingIds = orderingMasters.Select(p => p.deskId).ToList();
                if (status == 1)
                    where = where.And(a => !orderingIds.Contains(a.id));
                else
                    where = where.And(a => orderingIds.Contains(a.id));
            }
            list = base.AsQueryable().WhereIF(true, where.ToExpression()).OrderBy(a => a.sort).ToList();

            foreach (var item in list)
            {
                item.deskStatus = (int)GlobalEnumVars.TableStatus.Empty;
                item.amount = "";
                item.person = item.manQty.ObjToInt(1);
                item.personName = string.Format("{0}人", item.manQty);
                var orderings = orderingMasters.Where(p => p.deskId == item.id).ToList();
                if ((orderings != null) && (orderings.Count > 0))
                {
                    var ordering = orderings.FirstOrDefault();
                    item.amount = ordering.sumAllAmount.ToString("¥0.##");
                    item.person = ordering.person;
                    item.personName = string.Format("{0}/{1}人", ordering.person, item.manQty);
                    //开台时长
                    string times = "";
                    TimeSpan d3 = DateTime.Now.Subtract(ordering.orderDate);
                    //if ((d3.Days > 0) || (d3.Hours > 0)) times = times + string.Format("{0}小时", d3.Days * 24 + d3.Hours);
                    //if (d3.Minutes > 0) times = times + string.Format("{0}分钟", d3.Minutes);
                    times = string.Format("{0}分钟", d3.Days * 24 * 60 + d3.Hours * 60 + d3.Minutes);
                    item.timeName = times;
                    //餐台状态
                    if (ordering.foodCount == 0)
                        item.deskStatus = (int)GlobalEnumVars.TableStatus.TobePlaced;
                    else
                        item.deskStatus = ordering.status;

                    //拼台名称
                    if (orderings.Count > 1)
                        item.name = string.Format("{0}<拼{1}>", item.name, orderings.Count);
                }
            }

            return list;
        }

        /// <summary>
        /// 根据条件查询数据
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public corecmsfooddesk QueryDeskStatusById(long deskId)
        {
            var where1 = Expressionable.Create<corecmsfoodorderingmaster>();
            where1 = where1.And(p => p.deskId == deskId);
            var orderings = new corecmsfoodorderingmasterServices().AsQueryable().Where(where1.ToExpression()).ToList();
            var deskInfo = base.GetById(deskId);

            if (deskInfo == null) return null;

            deskInfo.deskStatus = (int)GlobalEnumVars.TableStatus.Empty;
            deskInfo.amount = "";
            deskInfo.person = deskInfo.manQty.ObjToInt(1);
            if ((orderings != null) && (orderings.Count > 0))
            {
                var ordering = orderings.FirstOrDefault();
                TimeSpan d3 = DateTime.Now.Subtract(ordering.orderDate);
                string times = "";
                //if ((d3.Days > 0) ||(d3.Hours > 0)) times = times + string.Format("{0}小时", d3.Days * 24+ d3.Hours);
                //if (d3.Minutes > 0) times = times + string.Format("{0}分钟", d3.Minutes);
                times = string.Format("{0}分钟", d3.Days * 24 * 60 + d3.Hours * 60 + d3.Minutes);
                deskInfo.timeName = times;
                deskInfo.amount = ordering.sumAllAmount.ToString("¥0.##");
                deskInfo.person = ordering.person;
                deskInfo.personName = string.Format("{0}/{1}人", ordering.person, deskInfo.manQty);
                if (ordering.foodCount == 0)
                    deskInfo.deskStatus = (int)GlobalEnumVars.TableStatus.TobePlaced;
                else
                    deskInfo.deskStatus = ordering.status;

                //拼台名称
                if (orderings.Count > 1)
                    deskInfo.name = string.Format("{0}<拼{1}>", deskInfo.name, orderings.Count);
            }
            return deskInfo;
        }

        /// <summary>
        /// 根据条件查询数据
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public DeskStatusDto QueryDeskStatus(long classId)
        {
            DeskStatusDto deskStatus = new DeskStatusDto();
            var where = Expressionable.Create<corecmsfooddesk>();
            where = where.And(a => a.isDelete == false && a.status == 1 && a.id > 0);
            var list = base.AsQueryable().Where(where.ToExpression()).OrderBy(a => a.sort).ToList();
            deskStatus.All = list.Count();

            var deskIds = list.Select(a => a.id).ToList();

            var where1 = Expressionable.Create<corecmsfoodorderingmaster>();
            where1 = where1.And(p => deskIds.Contains(p.deskId));
            var orderingMastersList = new corecmsfoodorderingmasterServices()
                .AsQueryable().Where(where1.ToExpression())
                .GroupBy(p => new { p.deskId,p.status })
                .Select(p => new DeskStatusList
                {
                    deskId = p.deskId,
                    status = p.status,
                    amount = SqlFunc.AggregateSum(p.sumAllAmount),
                }).ToList();

            deskStatus.TobePlaced = orderingMastersList.Where(p=>p.status == (int)GlobalEnumVars.TableStatus.TobePlaced).Count();
            deskStatus.TobeSettled = orderingMastersList.Where(p => p.status == (int)GlobalEnumVars.TableStatus.TobeSettled).Count();
            deskStatus.TobeSetAmount = orderingMastersList.Where(p => p.status == (int)GlobalEnumVars.TableStatus.TobeSettled
                || p.status == (int)GlobalEnumVars.TableStatus.PreSettled).Sum(p=>p.amount);
            deskStatus.PreSettled = orderingMastersList.Where(p => p.status == (int)GlobalEnumVars.TableStatus.PreSettled).Count();
            deskStatus.Empty = deskStatus.All - deskStatus.TobePlaced - deskStatus.TobeSettled - deskStatus.PreSettled - deskStatus.Settlement;

            //已结帐
            var orderMastersList = new corecmsfoodordermasterServices()
                .AsQueryable().Where(p => p.classId == classId)
                .GroupBy(p => new { p.deskId })
                .Select(p => new DeskStatusList
                {
                    deskId = p.deskId,
                    amount = SqlFunc.AggregateSum(p.sumAllAmount),
                }).ToList();

            deskStatus.Settlement = orderMastersList.Count();
            deskStatus.SettlementAmount = orderMastersList.Sum(p => p.amount);

            if (deskStatus.All >0)
            {
                float rate = (((float)deskStatus.All - (float)deskStatus.Empty) / (float)deskStatus.All) * 100;
                deskStatus.DeskOpenRate = string.Format("开台率:{0}%", Math.Floor(rate));
            }

            return deskStatus;
        }

        #endregion

        #region 获取默认的快餐台

        public void SetDeskSnack(corecmsstore corecmsstore)
        {
            var deskSnack = base.GetById(0);
            if (deskSnack == null)
            {
                deskSnack = new corecmsfooddesk();
                deskSnack.id = 0;
                deskSnack.storeId = corecmsstore.id;
                deskSnack.corpId = corecmsstore.corpId;
                deskSnack.isDelete = false;
                deskSnack.typeId = 0;
                deskSnack.number = "0";
                deskSnack.manQty = 0;
                deskSnack.useQty = 0;
                deskSnack.status = 1;
                deskSnack.name = " 快餐台";
                base.Insert(deskSnack);
            }
        }
        

        #endregion

    }
}
